# _*_ coding:utf-8 _*_
# @Time  : 2023.05.12
# @Author: zizlee
import re
import datetime
from ast import literal_eval
from typing import List

import pandas as pd
from fastapi import APIRouter, Body, Query, Path
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel, constr, conint, validator
from response import APIResponse
from utils import datetime_utils
from utils.hutool_utils import StringUtils
from db_utils import BaseDatabaseConnection, IndexDataBaseConnection
from settings import INDEX_DB_NAMES, DB_TABLE_MAX_COUNT


class DataIndexItem(BaseModel):
    name: constr(min_length=1)
    frequency: constr(min_length=1)
    unit: str
    start_date: constr(min_length=1)
    source: str = ''
    note: str

    @validator('name')
    def validate_name(cls, value):
        if not value:
            raise ValueError('名称不能为空')
        return StringUtils.full2half(value.strip())

    @validator('start_date')
    def validate_start_date(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('start_date invalidate! must be `yyyy-MM-dd`')
        return value


class FormulaCalculateIndexItem(BaseModel):
    formula: constr(min_length=12)
    start_date: str
    end_date: str

    @validator('start_date')
    def validate_start_date(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('start_date invalidate! must be `yyyy-MM-dd`')
        return value

    @validator('end_date')
    def validate_end_date(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('end_date invalidate! must be `yyyy-MM-dd`')
        return value


# 新建数据指标项目
class CreateDataIndexItem(DataIndexItem):
    plat: constr(min_length=1)
    plat_id: str


# 更新数据指标项目
class UpdateDataIndexItem(DataIndexItem):
    index_id: int
    state: conint(ge=0, le=1)
    is_active: conint(ge=0, le=1)


# 数据分组项目
class IndexGroupItem(BaseModel):
    name: constr(min_length=1)


# 创建数据分组项目
class CreateIndexGroupItem(IndexGroupItem):
    parent_id: int
    vcode: str


# 更新数据分组项目
class UpdateIndexGroupItem(IndexGroupItem):
    gid: int
    sort_num: int
    is_active: conint(ge=0, le=1)


# 分组内的指标
class DataGroupIndexItem(BaseModel):
    name: str
    alone: str = ''
    formula: str = ''
    stack: str = ''
    vcode: str

    @validator('alone')
    def validate_alone(cls, value):
        if not value:
            return ''
        try:
            alone = literal_eval(value)
            if not isinstance(alone, tuple) or len(alone) < 2:
                raise ValueError('不是长度为2的元组字符串.')
        except Exception as e:
            raise ValueError('配置1不合法: {}'.format(e))
        iid, chart = alone
        if not isinstance(iid, int) or chart not in ['line', 'bar']:
            raise ValueError('配置1不合法')
        return str(alone).replace("'", '"')

    @validator('formula')
    def validate_formula(cls, value):
        if not value:
            return ''
        try:
            formula, chart = literal_eval(value)
            eval(formula.replace('i', ''))
            if chart not in ['line', 'bar']:
                raise ValueError('配置2不合法')
        except Exception as e:
            raise ValueError('配置2不合法: {}'.format(e))
        return str(value).replace("'", '"')

    @validator('stack')
    def validate_stack(cls, value):
        if not value:
            return ''
        try:
            stack = literal_eval(value)
            if not isinstance(stack, list) or len(stack) < 2:
                raise ValueError('不是合法的长度为2的列表字符串.')
            for s in stack:
                y, iid, chart = s
                if y < 0 or y > 1 or not isinstance(iid, int) or chart not in ['line', 'bar']:
                    raise ValueError('配置3不合法')
        except Exception as e:
            raise ValueError('配置3不合法: {}'.format(e))
        return str(value).replace("'", '"')


# 创建分组内的指标
class CreateDataGroupIndexItem(DataGroupIndexItem):
    gid: int
    vcode: str
    unit: str = ''


# 更新分组内的指标
class UpdateDataGroupIndexItem(DataGroupIndexItem):
    rid: int
    unit: str
    sort_num: int
    is_primary: conint(ge=0, le=1)
    is_active: conint(ge=0, le=1)


# 指标行数据
class IndexRowItem(BaseModel):
    datadate: str
    datavalue: float

    @validator('datadate')
    def validate_datadate(cls, value):
        sd = datetime_utils.auth_yyyy_mm_dd(value)
        if not sd:
            raise ValueError('in rows `datadate` invalidate! must be `yyyy-MM-dd`')
        return value


class CreateIndexRowItem(IndexRowItem):
    pass


class UpdateIndexRowItem(IndexRowItem):
    rid: int
    is_active: conint(ge=0, le=1)

# ------------------------------------------- API执行类 ---------------------------------------


class DataIndexLib:
    def __init__(self, index_id: int = None):
        self.index_id = index_id

    def formula_index_list(self, formula_string: str):
        formula_str = re.sub(r'[()]', '', formula_string)
        formula_str = re.sub(r'[*/+-]', ',', formula_str)
        return formula_str.split(',')

    def formula_is_correct(self, formula_string: str, index_ids: list):
        if len(index_ids) < 1:
            return False
        correct = True
        test_formula = formula_string
        for i in index_ids:
            try:
                float(i)
            except ValueError:
                if len(i) < 8:
                    correct = False
                    break
                test_formula = test_formula.replace(i, '1')
            else:
                continue
        if correct and test_formula:
            try:
                eval(test_formula)
            except NameError:
                correct = False
            except SyntaxError:
                correct = False
        return correct

    def get_plat_index(self, plat, plat_id):  # 查询平台指标是否存在
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("SELECT id FROM datlib_index WHERE plat=%s AND plat_id=%s;", [plat, plat_id])
            exist = conn.cursor.fetchone()
        return exist

    def index_exist(self, plat, plat_id):
        exist = self.get_plat_index(plat=plat, plat_id=plat_id)
        return APIResponse.success(data={'exist': True if exist else False})

    def index_count(self):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("SELECT frequency,COUNT(id) As total FROM datlib_index GROUP BY frequency;")
            ret = conn.cursor.fetchall()
        return APIResponse.success(data={'counts': ret})

    def create_index(self, index_item: CreateDataIndexItem):
        exist = self.get_plat_index(plat=index_item.plat, plat_id=index_item.plat_id)
        if exist:
            return APIResponse.validate_error(detail='改平台指标ID已存在!')
        # 查询每个数据库表数量，每个最多8000个
        target_db = None
        total_count = 1
        with BaseDatabaseConnection() as conn:
            for db_name in INDEX_DB_NAMES:
                conn.cursor.execute("SELECT COUNT(id) as total FROM datlib_index WHERE db_name=%s;", [db_name])
                result = conn.cursor.fetchone()
                total_count += result['total']
                if result['total'] < DB_TABLE_MAX_COUNT:
                    target_db = db_name
                    break
            if not target_db:
                return APIResponse.server_error(detail='服务器错误，没有找到目标存储数据库.')
            if index_item.plat == 'ruizhi':
                table_name = f'ruizhi_r{total_count:0>11d}'
                plat_id = table_name.split('_')[1].upper()
            else:
                table_name = f'{index_item.plat}_r{total_count:0>11d}'
                plat_id = index_item.plat_id
            # 创建一个指标记录
            effect = conn.cursor.execute("""
                INSERT INTO datlib_index (name,plat,plat_id,db_name,tb_name,frequency,unit,start_date,source,note,is_active)
                VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);
            """, [index_item.name, index_item.plat, plat_id, target_db, table_name, index_item.frequency,
                  index_item.unit, index_item.start_date, index_item.source, index_item.note, 0])
            if effect:  # 新建成功才建表
                with IndexDataBaseConnection(db_name=target_db) as conn2:
                    conn2.create_table(table_name=table_name)
        return APIResponse.success()

    def retrieve_index(self, keyword: str = None, page: int = 1, page_size: int = 50):
        sql = """
            SELECT id,create_time,update_time,name,plat,plat_id,db_name,tb_name,frequency,unit,start_date,
            end_date,state,end_value,source,note,is_active FROM datlib_index
        """
        params = []
        if keyword:
            kw = keyword.replace(' ', '%')
            sql += f'WHERE name LIKE %s OR plat_id=%s ORDER BY create_time DESC;'
            params.append(f'%{kw}%')
            params.append(keyword)
        else:
            sql += 'ORDER BY create_time DESC;'
        with BaseDatabaseConnection() as conn:
            ret = conn.query_paginator(sql, param=params, page=page, page_size=page_size)
        return APIResponse.success(data={'data': ret})

    def update_index(self, index_item: UpdateDataIndexItem):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
                UPDATE datlib_index SET name=%s,frequency=%s,unit=%s,start_date=%s,source=%s,note=%s,state=%s,is_active=%s 
                WHERE id=%s LIMIT 1;
            """, [index_item.name, index_item.frequency, index_item.unit, index_item.start_date, index_item.source,
                  index_item.note, index_item.state, index_item.is_active, self.index_id])
        return APIResponse.success(msg='修改指标信息成功!')

    def formula_calculate(self, formula_item: FormulaCalculateIndexItem):
        index_ids = self.formula_index_list(formula_item.formula)
        if not self.formula_is_correct(formula_item.formula, index_ids):
            return APIResponse.validate_error(detail='公式有误!')
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("SELECT id,db_name,tb_name,plat_id FROM datlib_index WHERE plat_id IN %s;", [index_ids])
            index_list = list(conn.cursor.fetchall())
            for idx in index_list:
                sql = "SELECT datadate,datavalue FROM {}.{} WHERE datadate>=%s AND datadate<=%s;".format(idx['db_name'], idx['tb_name'])
                conn.cursor.execute(sql, [formula_item.start_date, formula_item.end_date])
                idx['data'] = list(conn.cursor.fetchall())
        df = None
        for index_obj in index_list:
            if df is None:
                df = pd.DataFrame(index_obj['data'])
                df.rename(columns={'datavalue': index_obj['plat_id']}, inplace=True)
            else:
                tmp = pd.DataFrame(index_obj['data'])
                tmp.rename(columns={'datavalue': index_obj['plat_id']}, inplace=True)
                df = pd.merge(df, tmp, how='outer', on='datadate')
        df.eval(f'formula_value = {formula_item.formula}', inplace=True)  # pandas表达式计算
        df.dropna(inplace=True)  # 删除含有na的行
        df.sort_values(by='datadate', inplace=True)
        res_data = {
            'data': df.to_dict(orient='records'),
            'formula': formula_item.formula,
            'start_date': formula_item.start_date,
            'end_date': formula_item.end_date
        }
        return APIResponse.success(data=res_data)


# 指标的分组(品种下的指标分组)
class DataIndexGroup:
    def __init__(self, vcode: str = None, parent_id=0):
        self.vcode = vcode
        self.parent_id = parent_id

    def create_group(self, g_item: CreateIndexGroupItem):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("INSERT INTO datlib_index_group (name,parent_id,vcode,is_active) VALUES (%s,%s,%s,%s);",
                                [g_item.name, self.parent_id, self.vcode, 1])
        return APIResponse.success(msg='创建数据分组成功!')

    def delete_group(self, group_id: int):
        # 查询是否有子分组
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("SELECT id FROM datlib_index_group WHERE parent_id=%s LIMIT 1;", [group_id])
            children = conn.cursor.fetchone()
            if children:
                return APIResponse.validate_error(detail='请删除该分组的子分组再进行操作!')
            # 先删除组内的指标
            index_count = conn.cursor.execute("DELETE FROM datlib_group_index WHERE group_id=%s;", [group_id])
            # 再删除分组
            group_count = conn.cursor.execute("DELETE FROM datlib_index_group WHERE id=%s LIMIT 1;", [group_id])
        return APIResponse.success(msg=f'删除分组成功，删除组内指标{index_count}个,组{group_count}个!')


    def retrieve_groups(self):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
                SELECT id,name,parent_id,vcode,sort_num,is_active FROM datlib_index_group
                WHERE vcode=%s AND parent_id=%s ORDER BY sort_num;
            """, [self.vcode, self.parent_id])
            group_list = conn.cursor.fetchall()

        return APIResponse.success(data={'data': group_list})

    def update_group(self, g_item: UpdateIndexGroupItem):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("UPDATE datlib_index_group SET name=%s,sort_num=%s,is_active=%s WHERE id=%s LIMIT 1;",
                                [g_item.name, g_item.sort_num, g_item.is_active, g_item.gid])
        return APIResponse.success(msg='更新数据完成!')


# 分组内的指标
class DataGroupIndex:
    def __init__(self, gid: int = None):
        self.gid = gid

    @staticmethod
    def handle_item_data(item):
        is_alone, is_formula, is_stack = (0, 0, 0)
        if item.alone:
            is_alone = 1
            item.formula = ''
            item.stack = ''
        elif item.formula:
            is_formula = 1
            item.alone = ''
            item.stack = ''
        elif item.stack:
            is_stack = 1
            item.alone = ''
            item.formula = ''
        else:
            pass
        return is_alone, is_formula, is_stack

    def get_group_index(self):
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
               SELECT id,group_id,name,is_alone,alone,is_formula,formula,is_stack,stack,unit,vcode,sort_num,is_primary,is_active 
               FROM datlib_group_index WHERE group_id=%s ORDER BY sort_num;
            """, [self.gid])
            ret = list(conn.cursor.fetchall())
        return APIResponse.success(data={'data': ret})

    def create_group_index(self, item: CreateDataGroupIndexItem):
        is_alone, is_formula, is_stack = self.handle_item_data(item)
        if is_alone == 0 and is_formula == 0 and is_stack == 0:
            return APIResponse.success(msg='数据配置错误,没有增加任何记录.')
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
               INSERT INTO datlib_group_index (group_id,name,is_alone,alone,is_formula,formula,is_stack,stack,unit,vcode,
               is_primary,is_active) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);
            """, [item.gid, item.name, is_alone, item.alone, is_formula, item.formula, is_stack, item.stack, item.unit,
                  item.vcode, 0, 1])
        return APIResponse.success(msg='创建新指标完成')

    def update_group_index(self, item: UpdateDataGroupIndexItem):
        is_alone, is_formula, is_stack = self.handle_item_data(item)
        if is_alone == 0 and is_formula == 0 and is_stack == 0:
            return APIResponse.success(msg='数据配置错误,没有改变任何记录.')
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
                UPDATE datlib_group_index SET name=%s,is_alone=%s,alone=%s,is_formula=%s,formula=%s,is_stack=%s,stack=%s,
                unit=%s,sort_num=%s,is_primary=%s,is_active=%s
                WHERE id=%s LIMIT 1;
            """, [item.name, is_alone, item.alone, is_formula, item.formula, is_stack, item.stack, item.unit,
                  item.sort_num, item.is_primary, item.is_active, item.rid])
        return APIResponse.success()

    def delete_group_index(self, group_index_id: int):
        with BaseDatabaseConnection() as conn:
            c = conn.cursor.execute("DELETE FROM datlib_group_index WHERE id=%s LIMIT 1;", [group_index_id])
        return APIResponse.success(msg=f'删除成功，影响数据{c}条!')

    def clear_group_index(self):
        with BaseDatabaseConnection() as conn:
            c = conn.cursor.execute("DELETE FROM datlib_group_index WHERE group_id=%s;", [self.gid])
        return APIResponse.success(msg=f'删除成功，影响数据{c}条!')


# 指标具体数据
class DataIndexDetail:
    def __init__(self, index_id: int, page: int = 1, page_size: int = 100):
        self.index_id = index_id
        self.page = page
        self.page_size = page_size

    def get_index_row(self):
        # 取指标信息
        with BaseDatabaseConnection() as conn:
            conn.cursor.execute("""
                SELECT id,name,plat,plat_id,db_name,tb_name,frequency,unit,start_date,end_date,state,note,is_active
                FROM datlib_index WHERE id=%s LIMIT 1;
            """, [self.index_id])
            row = conn.cursor.fetchone()
        return row

    def index_detail(self):
        row = self.get_index_row()
        if not row:
            return APIResponse.no_content(msg='查询的数据记录不存在!')
        with IndexDataBaseConnection(db_name=row['db_name']) as conn:
            ret = conn.query_with_paginator(tb_name=row['tb_name'], page=self.page, page_size=self.page_size,
                                            ascending=False, is_all=True)
            ret['description'] = row
        return APIResponse.success(data=ret)

    def index_interval_detail(self, start: str, end: str):
        row = self.get_index_row()
        if not row:
            return APIResponse.no_content(msg='查询的数据记录不存在！')
        with IndexDataBaseConnection(db_name=row['db_name']) as conn:
            ret = conn.query_with_interval(tb_name=row['tb_name'], start_date=start, end_date=end, is_all=True)
        return APIResponse.success(data=ret)

    @staticmethod
    def filter_rows(rows, obj, contain=False):
        new_list = []
        new_start = obj['end_date']
        if not new_start:
            _d = datetime.datetime.strptime(obj['start_date'], '%Y-%m-%d') + datetime.timedelta(days=-1)
            new_start = _d.strftime('%Y-%m-%d')  # 数据开始日期
        if contain:
            for r in rows:
                if r.datadate <= new_start:
                    new_list.append(jsonable_encoder(r))
        else:
            for r in rows:
                if r.datadate > new_start:
                    new_list.append(jsonable_encoder(r))
        return new_list

    def update_index_row(self, detail_conn: IndexDataBaseConnection, tb_name: str):  # 更新指标信息
        detail_conn.cursor.execute("SELECT datadate,datavalue FROM {} WHERE datadate=(SELECT MAX(datadate) FROM {}) LIMIT 1;".format(tb_name, tb_name))
        max_row = detail_conn.cursor.fetchone()
        if max_row:
            # 更新指标信息
            with BaseDatabaseConnection() as conn:
                conn.cursor.execute("UPDATE datlib_index SET end_date=%s,end_value=%s WHERE id=%s LIMIT 1;",
                                    [max_row['datadate'], max_row['datavalue'], self.index_id])

    # 添加数据记录
    def add_index_detail(self, rows: List[CreateIndexRowItem]):  # 向一个指标添加数据
        if len(rows) < 1:
            return APIResponse.success(msg='添加完成,没有上传新数据.')
        obj = self.get_index_row()
        if not obj:
            return APIResponse.no_content(msg='操作的数据记录不存在!')

        new_data_list = self.filter_rows(rows=rows, obj=obj)
        if len(new_data_list) < 1:
            return APIResponse.no_content(msg=f'添加【{obj["name"]}】完成，没有检测到新数据!')

        new_data_list.sort(key=lambda x: x['datadate'])  # 升序

        with IndexDataBaseConnection(db_name=obj['db_name']) as conn:
            sql = "INSERT INTO {}(datadate,datavalue) VALUES (%(datadate)s,%(datavalue)s);".format(obj['tb_name'])
            count = conn.cursor.executemany(sql, new_data_list)
            if count > 0:
                self.update_index_row(detail_conn=conn, tb_name=obj['tb_name'])
        return APIResponse.success(msg=f'添加【{obj["name"]}】完成，新增数据{count}行.')

    # 修改数据记录
    def update_index_detail(self, rows: List[UpdateIndexRowItem]):
        if len(rows) < 1:
            return APIResponse.success(msg='更新完成,没有上传新数据.')
        obj = self.get_index_row()
        if not obj:
            return APIResponse.no_content(msg='操作的数据记录不存在!')

        new_data_list = self.filter_rows(rows=rows, obj=obj, contain=True)
        if len(new_data_list) < 1:
            return APIResponse.no_content(msg=f'更新【{obj["name"]}】完成，没有上传新数据!')
        with IndexDataBaseConnection(db_name=obj['db_name']) as conn:
            sql = """
                UPDATE `{}` SET datadate=%(datadate)s,datavalue=%(datavalue)s,is_active=%(is_active)s WHERE id=%(rid)s;
            """.format(obj['tb_name'])
            count = conn.cursor.executemany(sql, new_data_list)
            if count > 0:
                self.update_index_row(detail_conn=conn, tb_name=obj['tb_name'])
        return APIResponse.success(msg=f'更新【{obj["name"]}】完成，影响了{count}行.')

    # 清空数据
    def delete_index_values(self):
        obj = self.get_index_row()
        with IndexDataBaseConnection(db_name=obj['db_name']) as conn:
            conn.cursor.execute('TRUNCATE TABLE `{}`;'.format(obj['tb_name']))
            with BaseDatabaseConnection() as conn2:
                conn2.cursor.execute('UPDATE datlib_index SET end_date=NULL WHERE id=%s LIMIT 1;', [self.index_id])
        return APIResponse.success(msg=f'清空【{obj["name"]}】数据完成!')


data_index_api = APIRouter()


@data_index_api.get('/exist/')  # 检查指标是否存在
def exist_index(plat: str = Query(...), plat_id: str = Query(...)):
    return DataIndexLib().index_exist(plat=plat, plat_id=plat_id)


@data_index_api.get('/count/')  # 查询数据指标的量
def count_index():
    return DataIndexLib().index_count()


@data_index_api.post('/create/')  # 添加一个指标
def create_data_index(index_item: CreateDataIndexItem = Body(...)):
    return DataIndexLib().create_index(index_item=index_item)


@data_index_api.get('/retrieve/')  # 查询指标
def retrieve_data_index(kw: str = Query(...), page: int = Query(1), page_size: int = Query(50)):
    return DataIndexLib().retrieve_index(keyword=kw, page=page, page_size=page_size)


@data_index_api.put('/update/')  # 更新一个指标信息
def update_data_index(index_item: UpdateDataIndexItem = Body(...)):
    return DataIndexLib(index_item.index_id).update_index(index_item=index_item)


@data_index_api.post('/group/create/')  # 创建一个分组
def create_index_group(g_item: CreateIndexGroupItem = Body(...)):
    return DataIndexGroup(vcode=g_item.vcode, parent_id=g_item.parent_id).create_group(g_item=g_item)


@data_index_api.delete('/group/delete/')  # 删除一个分组
def delete_index_group(gid: int = Body(..., embed=True)):
    return DataIndexGroup().delete_group(group_id=gid)


@data_index_api.get('/group/retrieve/')  # 查询品种下分组
def retrieve_index_group(vcode: str = Query(...), parent: int = Query(0)):
    return DataIndexGroup(vcode=vcode, parent_id=parent).retrieve_groups()


@data_index_api.put('/group/update/')  # 修改品种下分组
def update_index_group(g_item: UpdateIndexGroupItem = Body(...)):
    return DataIndexGroup().update_group(g_item=g_item)


@data_index_api.get('/groupIndex/retrieve/')  # 查询组内的指标
def get_group_index(gid: int = Query(...)):
    return DataGroupIndex(gid=gid).get_group_index()


@data_index_api.post('/groupIndex/create/')  # 创建组内指标
def create_group_index(item: CreateDataGroupIndexItem = Body(...)):
    return DataGroupIndex().create_group_index(item=item)


@data_index_api.put('/groupIndex/update/')  # 更新组内的指标
def update_group_index(item: UpdateDataGroupIndexItem = Body(...)):
    return DataGroupIndex().update_group_index(item=item)


@data_index_api.delete('/groupIndex/delete/')  # 删除组内一个指标
def delete_group_index(giid: int = Body(..., embed=True)):
    return DataGroupIndex().delete_group_index(group_index_id=giid)


@data_index_api.delete('/groupIndex/clear/')  # 清空组内所有指标
def clear_group_index(gid: int = Body(..., embed=True)):
    return DataGroupIndex(gid=gid).clear_group_index()


@data_index_api.post('/formulaCalculate/')  # 指标公式计算
def formula_calculate(formula: FormulaCalculateIndexItem = Body(...)):
    return DataIndexLib().formula_calculate(formula_item=formula)


@data_index_api.get('/intervalData/')
def index_interval_data(index_id: int = Query(...), start: str = Query(...), end: str = Query(...)):
    return DataIndexDetail(index_id=index_id).index_interval_detail(start=start, end=end)


@data_index_api.get('/{index_id}/')
def index_detail(index_id: int = Path(...), page: int = Query(1), page_size: int = Query(100)):
    return DataIndexDetail(index_id=index_id, page=page, page_size=page_size).index_detail()



@data_index_api.post('/{index_id}/')
def add_index_rows(index_id: int = Path(...), rows: List[CreateIndexRowItem] = Body(...)):
    return DataIndexDetail(index_id=index_id).add_index_detail(rows=rows)


@data_index_api.put('/{index_id}/')
def update_index_rows(index_id: int = Path(...), rows: List[UpdateIndexRowItem] = Body(...)):
    return DataIndexDetail(index_id=index_id).update_index_detail(rows=rows)


@data_index_api.delete('/{index_id}/')
def delete_index_rows(index_id: int = Path(...)):
    return DataIndexDetail(index_id=index_id).delete_index_values()

